package org.robot.scm.platform.registry.strategy;

import com.google.common.collect.Lists;
import it.tdlight.jni.TdApi.Message;
import it.tdlight.jni.TdApi.MessageContent;
import it.tdlight.jni.TdApi.MessageText;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.robot.scm.platform.registry.TelegramRegistry;
import org.robot.scm.platform.server.handler.BaseHandler;
import org.robot.scm.platform.server.telegram.ScmTelegram;
import org.robot.scm.utils.RandomUtil;
import org.robot.scm.utils.StreamUtils;

/**
 * 文本类型信息处理
 *
 * @Author : Awn create on 2025/4/21 17:00
 */
@Slf4j
public class TextMessageHandler extends AbstractMessageHandler {

    @Override
    protected Class clazz() {
        return MessageText.class;
    }

    @Override
    protected String doProcess(ScmTelegram scmTelegram, Message message, MessageContent messageContent) {
        MessageText messageText = (MessageText) messageContent;
        String text = messageText.text.text;
        handleForScm(text, "");
        return text;
    }

    /**
     * 文本处理
     */
    public static void handleForScm(String msg, String fileName) {
        if (StringUtils.isBlank(msg)) {
            return;
        }

        if (!TelegramRegistry.likeEnvIds.isEmpty()) {
            return;
        }

        try {
            String text = replaceDigit(msg);

            // 消息包含执行，且包含了数字，认为是将要执行的环境ID
            if (likeMatcher(text)) {
                Pattern pattern = Pattern.compile("\\d+");
                Matcher matcher = pattern.matcher(text);
                while (matcher.find()) {
                    TelegramRegistry.likeEnvIds.add(Integer.valueOf(matcher.group()));
                }
            }

            // 所有环境
            if ((text.contains("所有") || text.contains("全部")) && text.contains("执行")) {
                TelegramRegistry.likeEnvIds.clear();
                TelegramRegistry.likeEnvIds.addAll(Lists.newArrayList(2, 3, 4, 6, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25));
            }

            // 所有除了其他的脚本
            if (((text.contains("所有") || text.contains("其他")) && text.contains("除"))) {
                TelegramRegistry.likeEnvIds.clear();
                TelegramRegistry.likeEnvIds.addAll(Lists.newArrayList(2, 3, 4, 6, 15, 16, 17, 18, 20, 21, 22));
            }

            // 消息如果是sql语句，认为将是要执行的sql语句
            if (BaseHandler.isSql(msg)) {
                String handledMsg = msg.contains(";") ? StringUtils.join(StreamUtils.filter(Arrays.asList(text.split(";")), e -> BaseHandler.isSql(e.trim())), ";") + ";" : msg;
                handledMsg = handledMsg.split("\n\n\n")[0];
                String sqlKey = RandomUtil.uuidNoLine();
                File destFile = new File("assets/telegram/" + sqlKey.concat(".sql"));
                try (OutputStream out = Files.newOutputStream(destFile.toPath())) {
                    out.write(handledMsg.getBytes(StandardCharsets.UTF_8));
                } catch (IOException e) {
                    log.warn("detect sql message to scm fail");
                }
                TelegramRegistry.likeSqlKey.set(sqlKey);
                TelegramRegistry.likeSqlFile.set(fileName);
            }

            // 如果包含SQL，则SELECT之前的移除
            else if (BaseHandler.likeSql(msg)) {
                List<String> handles = Arrays.asList(msg.split("\\r?\\n"));
                int index = 0;
                for (int i = 0; i < handles.size(); i++) {
                    if (BaseHandler.isSql(handles.get(i))) {
                        index = i;
                        break;
                    }
                }

                List<String> subList = handles.subList(index, handles.size());
                String joinSqls = StringUtils.join(subList, "\n");
                String handleSql = joinSqls.trim().endsWith(";") ? joinSqls : joinSqls + ";";
                String sqlKey = RandomUtil.uuidNoLine();
                File destFile = new File("assets/telegram/" + sqlKey.concat(".sql"));
                try (OutputStream out = Files.newOutputStream(destFile.toPath())) {
                    out.write(handleSql.getBytes(StandardCharsets.UTF_8));
                } catch (IOException e) {
                    log.warn("detect like sql message to scm fail");
                }
                TelegramRegistry.likeSqlKey.set(sqlKey);
                TelegramRegistry.likeSqlFile.set(fileName);
            }

            // 权限相关
            else if (likePermissions(text)) {
                String writeOpen = "GRANT INSERT ON dict.elot_tenant_pay_info TO 'elot'@'%';\n"
                        + "GRANT INSERT,UPDATE ON dict.payconfig TO 'elot'@'%';\n"
                        + "FLUSH PRIVILEGES;";
                String writeClose = "REVOKE INSERT ON dict.elot_tenant_pay_info FROM 'elot'@'%';\n"
                        + "REVOKE INSERT,UPDATE ON dict.payconfig FROM 'elot'@'%';\n"
                        + "FLUSH PRIVILEGES;";
                String sqlKey = RandomUtil.uuidNoLine();
                File destFile = new File("assets/telegram/" + sqlKey.concat(".sql"));
                if (text.contains("开")) {
                    try (OutputStream out = Files.newOutputStream(destFile.toPath())) {
                        out.write(writeOpen.getBytes(StandardCharsets.UTF_8));
                    } catch (IOException e) {
                        log.warn("write open permission to scm fail");
                    }
                } else if (text.contains("关") || text.contains("去掉")) {
                    try (OutputStream out = Files.newOutputStream(destFile.toPath())) {
                        out.write(writeClose.getBytes(StandardCharsets.UTF_8));
                    } catch (IOException e) {
                        log.warn("write close permission to scm fail");
                    }
                }
                TelegramRegistry.likeSqlKey.set(sqlKey);
                TelegramRegistry.likeSqlFile.set(fileName);
            }
        } catch (Exception e) {
            log.warn("handle for scm fail", e);
        }
    }

    /**
     * 有点像执行的话语
     */
    private static boolean likeMatcher(String text) {
        if (StringUtils.isBlank(text)) {
            return false;
        }

        // 不包含数字
        if (!containsDigit(text)) {
            return false;
        }

        // 包含执行、新增、删除...
        if (text.contains("执行") || text.contains("新增") || text.contains("删除")
                || text.contains("更新") || text.contains("修改") || text.contains("添加") || text.contains("修复") || text.contains("清除")) {
            return true;
        }

        // 开关、权限 等相关字符
        return likePermissions(text);
    }

    /**
     * 类似于权限相关的字符
     */
    private static boolean likePermissions(String text) {
        return (text.contains("开") || text.contains("关") || text.contains("去")) && (text.contains("下") || text.contains("掉") || text.contains("权限"));
    }

    /**
     * 中文套数替换为数字
     */
    private static String replaceDigit(String text) {
        return text.replaceAll("十五", "15")
                .replaceAll("十六", "16")
                .replaceAll("十七", "17")
                .replaceAll("十八", "18")
                .replaceAll("十九", "19")
                .replaceAll("二十", "20")
                .replaceAll("二十一", "21")
                .replaceAll("二十二", "22")
                .replaceAll("二十三", "23")
                .replaceAll("二十四", "24")
                .replaceAll("二十五", "25")

                .replaceAll("二", "2")
                .replaceAll("三", "3")
                .replaceAll("四", "4")
                .replaceAll("六", "6");
    }

    /**
     * 文本包含数字
     */
    private static boolean containsDigit(String str) {
        return str.matches(".*\\d.*");
    }

}
